﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace PhoneApp1
{
    public enum ItemType
    {
        Tower = 1,
        Enemy = 2,
        zd = 3,
    }
    public class Item : IDisposable
    {
        private static long _MaxID;
        public static long MaxID
        {
            get
            {
                _MaxID++;
                return _MaxID;
            }
        }
        public long ID { get; set; }
        public ItemType Type { get; set; }
        public string Image { get; set; }
        public int x { get; set; }
        public int y { get; set; }
        public int z { get; set; }
        public int width { get; set; }
        public int height { get; set; }
        public double sd { get; set; }
        public Shape ThisShape { get; set; }
        public GameBase Game { get; set; }
        public Timer timer { get; set; }
        public delegate void MouseClick(object o, MouseButtonEventArgs e);
        public Item(GameBase game)
        {
            this.Game = game;
        }

        public void RegisterEvents()
        {
            ThisShape.MouseLeftButtonUp += ThisShape_MouseLeftButtonUp;
            ThisShape.GotFocus += ThisShape_GotFocus;
            ThisShape.MouseLeftButtonDown += ThisShape_MouseLeftButtonDown;
        }

        void ThisShape_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            ThisShape.Stroke = new SolidColorBrush(Colors.Brown);
            ThisShape.StrokeThickness = 1;
            this.Game.SelectedItem = this;
        }

        void ThisShape_GotFocus(object sender, System.Windows.RoutedEventArgs e)
        {
            ThisShape.Stroke = new SolidColorBrush(Colors.Brown);
            ThisShape.StrokeThickness = 1;
        }

        void ThisShape_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {

            SetSelected();
            e.Handled = true;
        }

        public virtual void SetSelected()
        {
            this.Game.SelectedItem = this;
            ThisShape.Stroke = new SolidColorBrush(Colors.Brown);
            ThisShape.StrokeThickness = 1;
        }
        public virtual void SetNoSelected()
        {
            this.Game.SelectedItem = null;
            ThisShape.Stroke = new SolidColorBrush(Colors.Brown);
            ThisShape.StrokeThickness = 0;
        }

        public virtual void Draw()
        {

        }


        public void Dispose()
        {
            if (this.timer != null)
                this.timer.Dispose();
            Game.GameMap.Dispatcher.BeginInvoke(() =>
            {
                Game.GameMap.Children.Remove(this.ThisShape);
                this.ThisShape = null;
                this.Game.RemoveItem(this);
            });

        }
    }

    public class TowerItem : Item
    {
        public TowerItem(GameBase game)
            : base(game)
        {
            this.x = 30;
            this.y = 30;
            this.Type = ItemType.Tower;
            this.width = 20;
            this.height = 20;
            this.sd = 2;
            Rectangle rect = new Rectangle();
            rect.Width = this.width;
            rect.Height = this.height;
            rect.Fill = new SolidColorBrush(Colors.Blue);
            this.ThisShape = rect;
            base.RegisterEvents();
            this.Game.AddItem(this);
            this.Draw();
            IsCanSj = true;
            this.timer = new Timer(Fire, null, 0, (long)this.sd * 1000);

        }

        private void Fire(object state)
        {

            if (IsCanSj)
            {
                CreateZd();
                //IsCanSj = false;
            }
        }
        public override void Draw()
        {
            base.Draw();
            Canvas.SetLeft(this.ThisShape, this.x);
            Canvas.SetTop(this.ThisShape, this.y);
            Canvas.SetZIndex(this.ThisShape, this.z);
        }
        public bool CheckHasEmp()
        {
            return true;
        }
        private List<Item> EmpList;
        private Item CurEmp;
        private bool IsCanSj;
        public void CreateZd()
        {
            this.CurEmp = new Item(this.Game);
            this.CurEmp.x = 40;
            this.CurEmp.y = 20;
            ZdItem zd = new ZdItem(this.Game, this.x, this.y, CurEmp.x, CurEmp.y);
            //zd.Run();
        }
    }

    public class ZdItem : Item
    {
        public ZdItem(GameBase game, int sx, int sy, int tox, int toy)
            : base(game)
        {
            lock (this.Game)
            {
                this.Type = ItemType.zd;
                this.width = 2;
                this.height = 2;
                this.SX = sx;
                this.SY = sy;
                this.x = sx;
                this.y = sy;
                this.z = 20;
                this.ToX = tox;
                this.ToY = toy;
                JsJd();
                this.sd = 100;
                this.Draw();
                timer = new Timer(Run, null, 100, 100);
                this.ID = Item.MaxID;// this.Game.Zds.Count + 1;
                this.Game.AddItem(this);
            }
        }

        private void Run(object state)
        {
            LifeTime += 100;
            double p = sd * LifeTime / 1000;
            this.x = this.SX - (int)(p * Math.Cos(this.Jd));
            this.y = this.SY - (int)(p * Math.Sin(this.Jd));
            if (this.Game.CheckIsOver(this))
            {
                this.Dispose();
            }
            else
                Draw();
        }
        public double Jd { get; set; }
        public int SX { get; set; }
        public int SY { get; set; }
        public int ToX { get; set; }
        public int ToY { get; set; }
        public double LifeTime { get; set; }

        public override void Draw()
        {
            if (this.ThisShape == null)
            {
                this.Game.CreateShape(this);

            }
            this.Game.ItemRun(this);
        }
        private void JsJd()
        {
            int xx = ToX - SX;
            int yy = ToY - SY;
            if (xx == 0)
            {
                if (yy >= 0)
                    Jd = 90;
                else
                    Jd = 270;
            }
            else
            {
                Jd = (Math.Atan(yy / xx)) * (180 / Math.PI);
            }
        }
    }

    public class EnemyItem : Item
    {
        public EnemyItem(GameBase game)
            : base(game)
        {
            this.x = 30;
            this.y = 30;
            this.Type = ItemType.Enemy;
            this.width = 20;
            this.height = 20;
            this.sd = 1;
            Rectangle rect = new Rectangle();
            rect.Width = this.width;
            rect.Height = this.height;
            rect.Fill = new SolidColorBrush(Colors.Blue);
            this.ThisShape = rect;
            this.Game.AddItem(this);
            this.Draw();
            this.timer = new Timer(Run, null, 0, (long)this.sd * 1000);
        }

        public void Run(object state)
        {
            throw new NotImplementedException();
        }
    }
}
